from django.contrib import auth as django_auth
from django.db.models import Q
from django.shortcuts import get_object_or_404
from rest_framework import exceptions
from rest_framework import generics
from rest_framework import permissions
from rest_framework import response
from rest_framework import views

from rest_framework.authtoken.models import Token

from course import models as models_course

from django.shortcuts import get_object_or_404
import rest_framework as drf
from . import serializers
import  datetime
from account import models as models_account


class CourseCreateView(generics.CreateAPIView):
    permission_classes = (permissions.IsAuthenticated,)
    serializer_class = serializers.CourseBaseSerializer

    def post(self, request):
        account = request.user.account
        account_id = account.id

        if account.role != "2":
            drf.serializers.ValidationError("您没有创建课程的权限！")

        start_time = request.data.get('start_time')
        end_time = request.data.get('end_time')
        if start_time > end_time:
            pass

        language = request.data.get('programming_language')
        language_eu = ['C', 'C++', 'Java', 'Fortran']
        if not language in language_eu:
            raise drf.serializers.ValidationError('未找到当前语言类型')

        max_num=request.data.get('student_num')
        if  max_num <= 0:
            raise drf.serializers.ValidationError('课程总人数应该大于0')

        account_name = account.real_name

        course = models_course.Course.objects.create(
            course_name=request.data.get('course_name'),
            status=1,
            programming_language=language,
            account_id=account_id,
            account_name=account_name,
            start_time=start_time,
            end_time=end_time,
            assignment_id=-1,
            number=0,
            max_num=max_num,
        )
        course.course_image = request.data.get('course_image', None)
        course.save()
        # create a classroom assignment--------------
        assignment = models_course.Assignment.objects.create(
            course_id=course.id,
            dead_line=datetime.datetime.now(),
            title="课堂作业",
            type="1",
        )
        ####create a Ti for the classroom assignment-----
        ti = models_course.Ti.objects.create(
            course_id=course.id,
            assignment_id=assignment.id,
            text="课程《"+course.course_name+"》的课堂作业",
        )
        course.assignment_id = assignment.id
        course.ti_id = ti.id
        course.save()

        data=serializers.CourseBaseSerializer(course).data
        return response.Response(data)


class CourseUpdateView(generics.CreateAPIView):
    permission_classes = (permissions.IsAuthenticated,)
    serializer_class = serializers.CourseUpdateSerializer

    def post(self,request):
        account=request.user.account
        course_id = request.data.get('course_id')
        status = request.data.get('status')
        account_id=account.id
        if not models_course.Course.objects.filter(id=course_id, account_id=account_id).exists():
            raise drf.serializers.ValidationError("您没有修改该课程的权限")

        course=models_course.Course.objects.get(id=course_id)
        if not course:
            raise drf.serializers.ValidationError("获取课程信息失败！")
        course.status=status
        course.save()

        return response.Response('修改课程成功！')



class CourseApplyView(generics.CreateAPIView):
    permission_classes = (permissions.IsAuthenticated,)
    serializer_class = serializers.CourseApplySerializer

    def create_assignment(self,course,account_id):

        myAssignment=models_course.MyAssignment.objects.create(
            assignment_id=course.assignment_id,
            account_id=account_id,
            ti_id=course.ti_id,
        )
        return  myAssignment

    def post(self, request):
        try:
            status = request.data.get('status')
            account_id_list = request.data.get('account_id')  ##account_id is the student account ID
            course_id = request.data.get('course_id')
        except:
            raise drf.serializers.ValidationError('未能找到全部参数')

        status_eu=['1','2','3','4']
        if not status in status_eu:
            raise drf.serializers.ValidationError('status参数错误')

        course=models_course.Course.objects.filter(id=course_id,status='1')
        if not course.exists() or  course[0].status!="1":
            raise drf.serializers.ValidationError('课程不存在')


        course = models_course.Course.objects.get(id=course_id,status='1')
        if (status=="3"):
            if  (course.number>=course.max_num) or (course.apply_number>=course.max_num):
                raise drf.serializers.ValidationError('课程人数已满')
            #用户申请
            try:
                account_id=request.user.account.id
                item = models_course.StudentCourse.objects.get(
                    Q(account_id=account_id) & Q(course_id=course_id)
                )
            except:
                if  account_id==course.account_id :
                    raise drf.serializers.ValidationError('不能申请自己的课程')
                item = models_course.StudentCourse.objects.create(
                    account_id=account_id, course_id=course_id, status="3",
                )

                course.apply_number+=1
                item.status = "3"
                item.save()
                course.save()
            else:
                if item.status=='3':
                    raise drf.serializers.ValidationError('申请中，请勿重复申请！')
                elif  item.status=='1':
                    raise drf.serializers.ValidationError('您已经拥有该课程！')
                else:
                    course.apply_number += 1
                    course.save()
                    item.status = "3"
                item.save()
        elif (status == "4"):
            try :
                item = models_course.StudentCourse.objects.get(
                    Q(account_id=account_id_list[0]) & Q(course_id=course_id) & Q(status = '1'))
            except:
                raise  drf.serializers.ValidationError("学生与课程不匹配！")
            item.status = "4"
            course.number -= 1
            item.save()
            course.save()
        elif status=="2":
            # 用户删除
            try :
                item = models_course.StudentCourse.objects.get(
                    Q(account_id=request.user.account.id) & Q(course_id=course_id) & Q(status='1')
                )
            except:
                raise  drf.serializers.ValidationError("学生不在该课程中！")
            item.status = "2"
            course.number -= 1
            item.save()
            course.save()
        else :
            account = request.user.account
            if  account.role == '1':
                raise drf.serializers.ValidationError("学生不具有该操作权限！")

            for account_id in account_id_list:
                try:
                    item = models_course.StudentCourse.objects.get(
                        Q(account_id = account_id) & Q(course_id=course_id) & Q(status = '3')
                    )
                except:
                    raise drf.serializers.ValidationError("课程不存在或者学生没有申请该课程！")

                if  status == '1':
                    item.status = "1"
                    course.apply_number -= 1
                    course.number += 1
                    # -add a classroom assignment in MyAssignment Table-------
                    if not models_course.MyAssignment.objects. \
                            filter(ti_id=course.ti_id, account_id=account_id).exists():
                        self.create_assignment(course, account_id)
                    item.save()
                    course.save()
                    assignment_list = models_course.Assignment.objects.filter(course_id=course_id)
                    for assignment in assignment_list:
                        ti_list = models_course.Ti.objects.filter(assignment_id=assignment.id)
                        for ti in ti_list:
                            try:
                                models_course.MyAssignment.objects.get(account_id=account_id,assignment_id=assignment.id,ti_id=ti.id)
                            except:
                                models_course.MyAssignment.objects.create(
                                    account_id=account_id,
                                    assignment_id=assignment.id,
                                    ti_id=ti.id,
                                )
                elif status == '0':
                    course.apply_number -= 1
                    item.status = "0"
                    item.save()
                    course.save()
                else:
                    raise drf.serializers.ValidationError("status值错误！")

        return  response.Response("修改学生状态成功！")

class CourseMyAllCourseView(views.APIView):
    permission_classes = (permissions.IsAuthenticated,)
    def get(self, request):
        account=request.user.account

        mycourse_list = []
        if account.role == '2':  # 老师
            mycourse_list = models_course.Course.objects.filter(account_id=account.id,status='1')
        elif account.role == '1':  # 学生
            course_id_list = models_course.StudentCourse.objects.filter(account_id=account.id,status='1')
            for course_id_item in course_id_list:
                try:
                    course_item = models_course.Course.objects.get(id=course_id_item.course_id,status='1')
                    mycourse_list.append(course_item)
                except:
                    continue
        courses_data = serializers.CourseMyAllCourseSerializer(mycourse_list, many=True).data
        return response.Response(courses_data)


class CourseSearchView(views.APIView):

    def get(self, request):
        searchType = request.GET.get('search_type')
        key=request.GET.get('keyword')
        courses=None
        if str(key) != '':
            if str(searchType) == '0':
                courses = models_course.Course.objects.filter(course_name__icontains=str(key),status='1')
            elif str(searchType) =='1':
                courses = models_course.Course.objects.filter(account_name__icontains=str(key),status='1')
            else:
                raise drf.serializers.ValidationError('searchType错误')
        else:
            courses = models_course.Course.objects.filter(status='1')
        data = serializers.CourseMyAllCourseSerializer(courses,many=True).data
        return response.Response(data)


class CourseRetrieveUpdateView(generics.RetrieveUpdateAPIView):
    permission_classes = (permissions.IsAuthenticated,)
    serializer_class = serializers.CourseUpdateSerializer

    def get_object(self):
        obj = get_object_or_404(models_course.Course, pk=self.kwargs['pk'])
        return obj


class CourseAllAssignmentsView(views.APIView):
    permission_classes = (permissions.IsAuthenticated,)
    def get(self, request):
        account = request.user.account
        account_id=account.id
        assignment_type=request.GET.get('assignment_type')
        filter_by_course=request.GET.get('filter_by_course')

        course_list = []
        if  account.role == '2':
            course_list = models_course.Course.objects.filter(account_id=account.id,status='1')
        elif account.role == '1':
            student_course_list = models_course.StudentCourse.objects.filter(account_id=account.id,status='1')
            for student_course in student_course_list:
                try:
                    course_item= models_course.Course.objects.get(id=student_course.course_id,status='1')
                    course_list.append(course_item)
                except:
                    continue

        all_assignments = []
        print("student_course_list")

        for course_item in course_list:

            if  filter_by_course=='':
                pass
            else:
                pass

            if assignment_type == '0':
                assignment_list = models_course.Assignment.objects.filter(course_id=course_item.id,
                                                                          type='0').order_by('dead_line')
            elif assignment_type == '1':
                assignment_list = models_course.Assignment.objects.filter(course_id=course_item.id,
                                                                          type='1').order_by('dead_line')
            else:
                raise drf.serializers.ValidationError("作业类型错误")

            for assignment_item in assignment_list:
                try:
                    course=models_course.Course.objects.get(id=assignment_item.course_id)
                except:
                    course_name=''
                assignment = serializers.CourseAllAssignmentSerializer.Struct(
                    programming_language=course_item.programming_language,
                    title=assignment_item.title,
                    type=assignment_item.type,
                    create_time=assignment_item.create_time,
                    dead_line=assignment_item.dead_line,
                    assignment_id=assignment_item.id,
                    course_name=course.course_name,
                    course_id=course.id
                )
                all_assignments.append(assignment)

        data= serializers.CourseAllAssignmentSerializer(all_assignments, many=True).data
        return response.Response(data)


class CourseCreateAssignmentView(generics.CreateAPIView):
    permission_classes = (permissions.IsAuthenticated,)
    serializer_class = serializers.CourseCreateAssignmentSerializer

    def post(self,request):
        course_id = request.data.get('course_id')
        account=request.user.account
        if account.role=="1":
            raise drf.serializers.ValidationError('学生无此权限！')

        try:
            course=models_course.Course.objects.get(id=course_id,account_id=account.id,status='1')
        except:
            raise drf.serializers.ValidationError('未找到有效课程')
        else:
            if course.status != "1":
                print(course_id)
                raise drf.serializers.ValidationError('课程不存在')


        type=request.data.get('type')
        tis=request.data.get('tis')
        dead_line=request.data.get('dead_line')
        assignment=models_course.Assignment.objects.create(
        course_id=course_id,
        dead_line = datetime.datetime.strptime(dead_line,"%Y-%m-%d"),
        title=request.data.get('title'),
        type=type,
        )

        members=models_course.StudentCourse.objects.filter(course_id=course_id, status='1')
        for txt in tis:
            tt = models_course.Ti.objects.create(
                course_id=course_id,
                assignment_id=assignment.id,
                text=txt,
            )

            for member in members:

                myAssignment=models_course.MyAssignment.objects.create(
                    assignment_id=assignment.id,
                    account_id=member.account_id,
                    ti_id=tt.id,
                )

        return response.Response("作业创建成功！")



class CourseAssignmentTextView(views.APIView):
    permission_classes = (permissions.IsAuthenticated,)

    def get(self, request):
        assignment_id = request.GET.get('assignment_id')
        account=request.user.account
        if account.role == '1':
            try:
                validate_1 = models_course.Assignment.objects.get(id=assignment_id)
                validate_2 = models_course.StudentCourse.objects.get(account_id=account.id,
                                                                     course_id=validate_1.course_id,
                                                                     status='1')
                validate_5=models_course.Course.objects.get(id=validate_1.course_id,status='1')
            except:
                print(validate_2.id)
                #print(validate_5.id)
                raise drf.serializers.ValidationError('未找到该学生的该有效作业')
        elif account.role == '2':
            try:
                validate_3 = models_course.Assignment.objects.get(id=assignment_id)
                validate_4 = models_course.Course.objects.get(account_id=account.id,
                                                                     id=validate_3.course_id,status='1')
            except:
                raise drf.serializers.ValidationError('未找到该老师的该作业')


        ti_list = models_course.Ti.objects.filter(assignment_id = assignment_id)
        assignment_text=[]

        if account.role == '1':
            for ti in ti_list:
                try:
                    myassignment = models_course.MyAssignment.objects.get(ti_id=ti.id,account_id=account.id)
                    project_id=myassignment.project_id
                except:
                    project_id=-1
                    #raise drf.serializers.ValidationError('用户没有该作业')
                item = serializers.CourseAssignmentTextSerializer.Struct(ti.id, ti.text, project_id)
                assignment_text.append(item)
        elif account.role == '2':
            for ti in ti_list:
                item = serializers.CourseAssignmentTextSerializer.Struct(ti.id, ti.text,-1)
                assignment_text.append(item)


        text_list = serializers.CourseAssignmentTextSerializer(assignment_text,many=True).data
        return response.Response(text_list)


class CourseAllStudentView(views.APIView):
    permission_classes = (permissions.IsAuthenticated,)
    def get(self, request):
        course_id = request.GET.get('course_id')
        status = str(request.GET.get('status'))
        account=request.user.account
        allstudent=[]

        try:
            validate_1=models_course.Course.objects.get(id=course_id,status='1')
        except:
            raise drf.serializers.ValidationError('未找到对应的有效课程！')
        if account.role == '1':  # 学生请求
            try:
                student_course = models_course.StudentCourse.objects.get(account_id=account.id, course_id=course_id)
            except:
                raise drf.serializers.ValidationError('未找到该学生的该课程！')
            student_pass_list = models_course.StudentCourse.objects.filter(course_id=course_id, status='1')
        elif account.role == '2': #老师请求
            try:
                student_course = models_course.Course.objects.get(account_id=account.id, id=course_id)
            except:
                raise drf.serializers.ValidationError('未找到该老师的该课程！')
            if status == '1':
                student_pass_list = models_course.StudentCourse.objects.filter(course_id=course_id, status='1')
            elif status == '3':
                student_pass_list = models_course.StudentCourse.objects.filter(course_id=course_id, status='3')
            else:
                raise drf.serializers.ValidationError('status错误！')

        for stu in student_pass_list:
            account=models_account.Account.objects.get(id=stu.account_id)
            class_name=None
            class_id=None
            student_number=None
            if  account.role=='1':
                info=models_account.StudentInfo.objects.get(id=account.member_id)
                class_id=info.class_id
                student_number=info.student_number
                if class_id != None:
                    class_name=models_account.Class.objects.get(id=class_id).class_name

            student=serializers.CourseAllStudentSerializer.Struct(account_id=stu.account_id,
                                                                  class_name=class_name,
                                                                  real_name=account.real_name,
                                                                  class_id = class_id,
                                                                  student_number=student_number)
            allstudent.append(student)
        data =serializers.CourseAllStudentSerializer(allstudent,many=True).data
        return response.Response(data)



class CourseAssignmentDetailView(views.APIView):
    permission_classes = (permissions.IsAuthenticated,)
    def get(self, request):
        ti_id = request.GET.get('ti_id')
        account = request.user.account
        if account.role=='1':
            raise drf.serializers.ValidationError('该接口只允许老师访问！')
        try:
            validate_1=models_course.Ti.objects.get(id=ti_id)
            assignment = models_course.Assignment.objects.get(id=validate_1.assignment_id)
            validate_2=models_course.Course.objects.get(id=validate_1.course_id,account_id=account.id,status='1')
        except:
            raise drf.serializers.ValidationError('该题不属于该老师！')
        detail_list=[]

        print(assignment)
        if  assignment.type== '0':
            myAssignment_list = models_course.MyAssignment.objects.filter(ti_id=ti_id)

        elif assignment.type == '1':
            now = datetime.datetime.now()
            start = now - datetime.timedelta(hours=0, minutes=40, seconds=0)
            myAssignment_list = models_course.MyAssignment.objects.filter(ti_id=ti_id,
                                                                          updated_time__gt=start)

        for myAssignment_item in myAssignment_list:
            try:
                account = models_account.Account.objects.get(id=myAssignment_item.account_id)
            except:
                continue
            class_name=None
            try:
                info = models_account.StudentInfo.objects.get(id=account.member_id)
                class_item = models_account.Class.objects.get(id=info.class_id)
                class_name=class_item.class_name
            except:
                pass
            studentInfo = models_account.StudentInfo.objects.get(id=account.member_id)

            if myAssignment_item.submited == False:
                compile_successed=False
            else:
                compile_successed=myAssignment_item.compile_successed
            detail = serializers.CourseAssignmentDetailSerializer.Struct(
                real_name=account.real_name,
                student_number=studentInfo.student_number,
                submited=myAssignment_item.submited,
                compile_successed=compile_successed,
                project_id=myAssignment_item.project_id,
                class_name=class_name
            )

            detail_list.append(detail)

        data =serializers.CourseAssignmentDetailSerializer(detail_list,many=True).data
        return response.Response(data)
